package com.lancer.dynamic.thread.pool;

import com.lancer.dynamic.thread.pool.domain.TheadPoolMap;
import com.lancer.dynamic.thread.pool.config.ThreadPoolConfig;
import com.lancer.dynamic.thread.pool.domain.Result;
import com.lancer.dynamic.thread.pool.domain.ThreadPoolInfo;
import com.lancer.dynamic.thread.pool.domain.ThreadPoolListVO;
import com.lancer.dynamic.thread.pool.service.ThreadPoolServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.BooleanUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.TimeUnit;

@Component
@Slf4j
public class ThreadPoolMonitor {


    @Resource
    private JavaMailSender mailSender;
    @Autowired
    private ThreadPoolServiceImpl threadPoolServiceImpl;

    // 新增：记录线程池首次触发告警的时间
    private static ConcurrentHashMap<String, Long> firstAlertTimeMap = new ConcurrentHashMap<>();
//    @PostConstruct
//    public void init() {
//        // 启动线程池监控
//        monitor();
//    }
//
//    // 监控常驻线程，监控线程池队列告警
//
//    public void monitor() {
//        Thread thread = new Thread(new Runnable() {
//            @Override
//            public void run() {
//                while (true) {
//                    try {
//                        Thread.sleep(100);
//                    } catch (InterruptedException e) {
//                        throw new RuntimeException(e);
//                    }
//                    try {
//                        ConcurrentHashMap<String, LancerExecutor> executorMap = TheadPoolMap.POOL_EXECUTOR_MAP;
//                        Collection<LancerExecutor> threadPoolExecutors = executorMap.values();
//                        for (LancerExecutor executor : threadPoolExecutors) {
//                            String poolName = executor.getPoolName(); // 或者用你自己的方式获取名称
//                            int queueSize = executor.getQueue().size();
//                            int capacity = executor.getQueue().remainingCapacity() + queueSize;
//                            if (capacity > 0) {
//                                double usageRate = (double) queueSize / capacity;
//                                if (usageRate >= 0.7) {
//                                    long currentTime = System.currentTimeMillis();
//                                    Long firstAlertTime = firstAlertTimeMap.get(poolName);
//
//                                    // 如果是首次触发
//                                    if (firstAlertTime == null) {
//                                        // 记录首次触发时间
//                                        firstAlertTimeMap.put(poolName, currentTime);
//
////                                        // 发送第一次邮件提醒
////                                        SimpleMailMessage message = new SimpleMailMessage();
////                                        message.setFrom("13503905942@163.com");
////                                        message.setTo("2872392768@qq.com");
////                                        message.setSubject("线程池队列告警 - 初次：" + poolName);
////                                        message.setText("线程池 [" + poolName + "] 的任务队列已达到 " + queueSize +
////                                                "，容量为 " + capacity + "，使用率：" + String.format("%.2f", usageRate * 100) + "%");
////                                        mailSender.send(message);
//                                        log.warn("线程池队列即将满，请及时处理：{} 使用率{}", poolName, String.format("%.2f", usageRate * 100) + "%");
//                                    } else if (currentTime - firstAlertTime >= 60_000) { // 超过1分钟
//                                        // 发送最终警告邮件
////                                        SimpleMailMessage finalMessage = new SimpleMailMessage();
////                                        finalMessage.setTo("2872392768@qq.com");
////                                        finalMessage.setSubject("线程池队列告警 - 最终预警：" + poolName);
////                                        finalMessage.setText("线程池 [" + poolName + "] 的任务队列持续高负载，已超过1分钟。当前使用率：" + String.format("%.2f", usageRate * 100) + "%");
////                                        mailSender.send(finalMessage);
//                                        log.warn("线程池队列持续高负载，请紧急处理：{} 使用率{}", poolName, String.format("%.2f", usageRate * 100) + "%");
//
//                                        // 清除记录，防止重复发送
//                                        firstAlertTimeMap.remove(poolName);
//                                    }
//                                } else {
//                                    // 如果占用率低于70%，清除记录
//                                    firstAlertTimeMap.remove(poolName);
//                                }
//                            }
//                        }
//                    } catch (Exception e) {
//                        log.error("线程池监控异常：{}", e.getMessage());
//                    }
//                }
//            }
//        });
//        thread.setDaemon(true);
//        thread.start();
//    }



    public Result<List<ThreadPoolListVO>> queryList() {
        ConcurrentHashMap<String, LancerExecutor> executorMap = TheadPoolMap.POOL_EXECUTOR_MAP;
        List<ThreadPoolListVO> threadPoolInfos = new ArrayList<>();
        executorMap.forEach((k, v) -> {
            ThreadPoolListVO info = new ThreadPoolListVO();
            info.setPoolName(k);
            info.setActiveThreads(v.getActiveCount());
            info.setQueueSize(v.getQueue().size());
            info.setCompletedTasks(v.getCompletedTaskCount());
            threadPoolInfos.add(info);
        });
        return Result.success(threadPoolInfos);
    }

    public Result<ThreadPoolInfo> queryDetails(String poolName) {
        // 判断是否存在当前的线程池
        if (!TheadPoolMap.POOL_EXECUTOR_MAP.containsKey(poolName)) {
            return Result.failed("不存在该线程池");
        }
        // 设置详情
        LancerExecutor executor = TheadPoolMap.POOL_EXECUTOR_MAP.get(poolName);
        ThreadPoolInfo info = new ThreadPoolInfo();
        info.setPoolName(poolName);
        RejectedExecutionHandler rejectedExecutionHandler =executor.getRejectedExecutionHandler();
        info.setRejectEnum(executor.getRejectEnum());
        info.setActiveThreads(executor.getActiveCount());
        info.setQueueCapacity(executor.getQueue().remainingCapacity()+executor.getQueue().size());
        info.setCorePoolSize(executor.getCorePoolSize());
        info.setMaxPoolSize(executor.getMaximumPoolSize());
        info.setKeepAliveTime((int) executor.getKeepAliveTime(TimeUnit.SECONDS));
        // 拒接策略翻译
        info.setRejectText(info.getRejectEnum().getRejectText());
        // 获取当前任务队列中的任务数
        info.setQueueSize(executor.getQueue().size());
        return Result.success(info);
    }

    public Result<String> shutdown(String poolName, Boolean isForceStop) {
        LancerExecutor executor = TheadPoolMap.POOL_EXECUTOR_MAP.get(poolName);
        // 判断是否存在当前的线程池
        if (!TheadPoolMap.POOL_EXECUTOR_MAP.containsKey(poolName)) {
            return Result.failed("不存在该线程池");
        }

        // 如果线程池已经关闭，直接返回提示
        if (executor.isShutdown()) {
            return Result.success("线程池已处于关闭状态：" + executor.toString());
        }

        // 根据参数选择关闭方式
        if (BooleanUtils.isTrue(isForceStop)) {
            log.warn("正在强制关闭线程池：{}", poolName);
            List<Runnable> tasks = executor.shutdownNow();
            return Result.success("强制关闭成功，共中断 " + tasks.size() + " 个未执行的任务，线程池信息：" + executor.toString());
        } else {
            log.info("正在正常关闭线程池：{}", poolName);
            executor.shutdown();
            return Result.success("已提交关闭请求，线程池信息：" + executor.toString());
        }
    }

    public Result<String> buildOrUpdate(ThreadPoolInfo threadPoolInfo) {
        // 创建一个新的线程池
        ThreadPoolConfig config = new ThreadPoolConfig();
        BeanUtils.copyProperties(threadPoolInfo, config);
        // 校验如果核心线程池大于最大线程池，则不允许创建
        if (config.getCorePoolSize() > config.getMaxPoolSize()) {
            return Result.failed("核心线程池大小不能大于最大线程池大小");
        }
        threadPoolServiceImpl.addOrUpdateThreadPool(config);
        return Result.success("创建成功");
    }

}
